package com.easthome.service.impl;

import com.easthome.constant.Constants;
import com.easthome.entity.Goods;
import com.easthome.pojo.vo.CartItemVO;
import com.easthome.pojo.vo.CartVO;
import com.easthome.service.CartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author cxiaoy
 * @Date 2022/10/20 15:42
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 先判断 nn买没买过冰红茶：
     * hget(nn的id,冰红茶的id)可以拿的存在购物车中的商品信息。
     * 我们需要这个商品信息 封装到CartItemVO中。
     *
     * @param goods
     * @param userId
     * @return
     */
    @Override
    public int addToCart(Goods goods, Integer userId) {
        HashOperations ops = redisTemplate.opsForHash();
        //从redis中获取 nnID的goodsId(即念念的冰红茶)-->CartItem（冰红茶的商品项）
        CartItemVO cartItemVO = (CartItemVO) ops.get(Constants.CART_KEY + userId, goods.getGoodsId());//定义一下前面的前缀。hget key field1 -->value1
        if(cartItemVO==null){//首次将冰红茶加入购物车
            cartItemVO = new CartItemVO();
            cartItemVO.setUnitPrice(goods.getUnitPrice());
            cartItemVO.setImgUrl(goods.getImgUrl());
            cartItemVO.setGoodsName(goods.getGoodsName());
            cartItemVO.setAmount(1);
            cartItemVO.setTotalPrice(goods.getUnitPrice());
            cartItemVO.setGoodsId(goods.getGoodsId());
        }else{
            cartItemVO.setAmount(cartItemVO.getAmount()+1);
            cartItemVO.setTotalPrice(cartItemVO.getUnitPrice().multiply(new BigDecimal(cartItemVO.getAmount().toString())));
        }
        ops.put(Constants.CART_KEY+userId,goods.getGoodsId(),cartItemVO);//将这个商品项，重新放到redis中。

        getCartTotalPrice(userId, ops);

        //测试效果。。
        CartItemVO cartItemVO1 = (CartItemVO)ops.get(Constants.CART_KEY + userId,goods.getGoodsId());
        System.out.println("cartItemVO1...."+cartItemVO1);

//        ops.put("cart_9527",1001,"cha...");//hset cart_9527 1001 "cha.."
//        System.out.println("从redis获取。。。。。"+ops.get("cart_9527", 1001));
        return 0;
    }

    private void getCartTotalPrice(Integer userId, HashOperations ops) {
        //购物车的总价格
        Set keys = ops.keys(Constants.CART_KEY + userId);//拿到nn这个key的所有field
        BigDecimal sum = new BigDecimal("0");
        for(Object key:keys){
            if(!key.toString().equals("totalPrice")){//如果遍历出来的key不是totalPrice，说明是goodsId
                sum = sum.add(((CartItemVO) ops.get(Constants.CART_KEY+ userId,key)).getTotalPrice());
            }
        }

        ops.put(Constants.CART_KEY + userId,"totalPrice",sum);
    }

    /*
    redis的hash:
    key(nn):
        field1 value1   field2 value2 ....fieldn  valuen
        mysql数据库：
            我们可以在数据库中写sql执行，我们还可以在java中写代码，jdbc这是最原始的。getConn,createStat,Result...
            queryRunner、mybatis...
        redis数据库：
            我们可以在小黑屏中，用set username nn指令，我们还可以在java中写代码，jedis这个是最原始的。
            redisTemplate封装了jedis...这个api可以操作redis数据库。
            redis:list  string  hash set  zset....
            redisTemplate可以.opsForHash、.opsForZSet等
            cartPD:key:nnid  f1 v1 f2 v2  ... fn vn
     */
    @Override
    public CartVO getCart(Integer userId) {
        HashOperations ops = redisTemplate.opsForHash();//redisAPI
        CartVO cartVO = new CartVO();//准备一个CartVO,一会儿从redis中取出数据后，存在这个对象中。并返回给前端
        List<CartItemVO> list = new ArrayList<>();
        Set keys = ops.keys(Constants.CART_KEY + userId);//获取念念购物车中的所有keys
        for(Object key:keys){//遍历keys，其中里面有一个totalPrice，还有一堆 goodsId
            if(key.toString().equals("totalPrice")){
                cartVO.setTotalPrice((BigDecimal) ops.get(Constants.CART_KEY + userId,key));
            }else{
                list.add((CartItemVO) ops.get(Constants.CART_KEY + userId,key));
            }
        }
        cartVO.setList(list);
        cartVO.setUserId(userId);
        return cartVO;
    }

    /*
    修改购物车的价格：
    把商品信息从购物车取出来存到cartItem对象中
    修改cartItem这个对象
        修改amount、修改小计、修改购物车总计
    再放回到redis中
     */
    @Override
    public int updateCart(Integer userId, Integer goodsId, Integer amount) {
        HashOperations ops = redisTemplate.opsForHash();
        //把商品信息从购物车取出来存到cartItem对象中
        CartItemVO cartItemVO = (CartItemVO)ops.get(Constants.CART_KEY + userId, goodsId);
        //修改cartItem这个对象
        //修改amount
        cartItemVO.setAmount(amount);
        //修改小计、
        cartItemVO.setTotalPrice(cartItemVO.getUnitPrice().multiply(new BigDecimal(cartItemVO.getAmount().toString())));
        //将修改完的cartItemVO存入redis中
        ops.put(Constants.CART_KEY+userId,goodsId,cartItemVO);
        //修改购物车总计
        getCartTotalPrice(userId,ops);
        return 1;
    }

    @Override
    public int removeCartItem(Integer userId, Integer goodsId) {
        HashOperations ops = redisTemplate.opsForHash();
        ops.delete(Constants.CART_KEY+userId,goodsId);
        this.getCartTotalPrice(userId,ops);
        return 1;
    }

    @Override
    public CartItemVO getCartItemVo(Integer userId,Integer goodsId) {
        HashOperations ops = redisTemplate.opsForHash();
        return (CartItemVO)ops.get(Constants.CART_KEY+userId,goodsId);
    }
}
